
class BiliParser {
  constructor(bilistr) {
    this.bilistr = bilistr;
    this.cursor = 0;
    this.currentCh = '';
    this.regex = new RegExp('\\[([\\s\\S]*?)\\]', 'g');
  }

  parse() {
    let match;
    let frontIndex = 0;
    while(match = this.regex.exec(this.bilistr)) {
      // check \
      const matchStr = match[0];
      const lastIndex = this.regex.lastIndex;
      const frontSlash = lastIndex - matchStr.length -1;
      const lastSlash = lastIndex - 1;
      let preStr = '';
      if ((frontSlash > 0 && this.bilistr[frontSlash] === '\\') 
      || (lastSlash > 0 && this.bilistr[lastSlash] === '\\')
      || !match[1]) {
        preStr += this.bilistr.substring(frontIndex, lastIndex);
        if (preStr) {
          console.log(`controller.action('${preStr}')`);
        }
      } else {
        preStr += this.bilistr.substring(frontIndex, frontSlash + 1);
        if (preStr) {
          console.log(`controller.action('${preStr}')`);
        }
        this._inlineParse(match[1], 0);
      }
      
      frontIndex = lastIndex;
    }

    console.log(`controller.action(${this.bilistr.substring(frontIndex)})`);

  }


  _inlineParse(content, index) {
    let cursor = index;
    let ch = content[cursor];
    if (ch === '*') {
      let speed = '';
      while(BiliParser.isNumber(content[++cursor])) {
        speed += content[cursor];
      }
      if (speed) {
        console.log(`controller.setSpeed(${speed})`);
      }
    } else if (ch === '-' || ch === '+') {
      let typestr = '';
      while(!BiliParser.isSymbol(content[++cursor])) {
        const tmpchar = content[cursor];
        // check slash
        if (BiliParser.isSlash(tmpchar)) {
          const symbol = content[++cursor];
          if (BiliParser.isSymbol(symbol)) {
            typestr += symbol;
            continue;
          }
        }
        typestr += tmpchar;
      }
      if (typestr) {
        const wordCount = typestr.length;
        console.log(`controller.action("${typestr}")`);
        if (ch === '-') {
          console.log(`controller.action(Bilibala.BACKSPACE, { wordCount: ${wordCount} })`);
        }
      }

    } else if (ch === '.') {
      let interval = '';
      while (BiliParser.isNumber(content[++cursor])) {
        interval += content[cursor];
      }
      if (interval) {
        console.log(`controller.action(Bilibala.STAY, { interval: ${interval} }")`);
      }
    } else {
      console.log(`controller.action('${content}')`);
    }

    if (content[cursor]) {
      this._inlineParse(content.substring(cursor), cursor);
    }
  }
}

BiliParser.isNumber = (char) => /\d/.test(char);
BiliParser.isSymbol = (char) => /[+.\-]/.test(char);
BiliParser.isSlash = (char) => /\\/.test(char);


const biliController = new BiliParser('[*900]hello,\\ [-world!+hello]human![.2000] I am a robot!');
biliController.parse();
